
#include "Baby.h"
#include "LevelManager.h"
#include "TextureManager.h"
#include "AudioUtils.h"
#include "hRandom.h"
#include "hMath.h"

const float LATERAL_CLOUD_HEIGHT = 0.47f;
const float CENTER_CLOUD_HEIGHT = 0.70f;
const float BABY_HEIGHT_OFFSET = 0.05f;

Baby::Baby(std::string _sName, eBabyPos _eBabyPos, int _iCloud) : AnimatedEntity(_sName, Vector2(-100, -100))
{
    m_iCloud = _iCloud;
    
    if (_sName == "chameleon")
    {
        m_oTongueEyes = new AnimatedEntity( "chameleon_EyesAndTongue", Vector2(-100,-100));
        m_oTongueEyes->setFlipHorizontal(_eBabyPos == BabyLeft);
    }
    else
    {
        m_oTongueEyes = NULL;
    }
    
    // set the mouth pos
    m_vMouthPos = LevelManager::instance().getMouthPos(_sName);
    
    switch(_eBabyPos)
    {
        case BabyLeft:
            m_vPosIn = Vector2(SB::SCREEN_WIDTH * 0.17, SB::SCREEN_HEIGHT * (LATERAL_CLOUD_HEIGHT + BABY_HEIGHT_OFFSET));
            m_vPosOut = Vector2(SB::SCREEN_WIDTH * 0.17, SB::SCREEN_HEIGHT * 1.1);
            m_vCloudPosIn = Vector2(SB::SCREEN_WIDTH * 0.17, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
            m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * -0.20, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
            break;

        case BabyCenter:
            m_vPosIn = Vector2(SB::SCREEN_WIDTH * 0.50, SB::SCREEN_HEIGHT * (CENTER_CLOUD_HEIGHT + BABY_HEIGHT_OFFSET));
            m_vPosOut = Vector2(SB::SCREEN_WIDTH * 0.50, SB::SCREEN_HEIGHT * 1.4);
            m_vCloudPosIn = Vector2(SB::SCREEN_WIDTH * 0.50, SB::SCREEN_HEIGHT * CENTER_CLOUD_HEIGHT);
            m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * -0.20, SB::SCREEN_HEIGHT * CENTER_CLOUD_HEIGHT);
            break;

        case BabyRight:
            m_vPosIn = Vector2(SB::SCREEN_WIDTH * 0.83, SB::SCREEN_HEIGHT * (LATERAL_CLOUD_HEIGHT + BABY_HEIGHT_OFFSET));
            m_vPosOut = Vector2(SB::SCREEN_WIDTH * 0.83, SB::SCREEN_HEIGHT * 1.1);
            m_vCloudPosIn = Vector2(SB::SCREEN_WIDTH * 0.83, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
            m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * 1.2, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
            break;
            
        default:
            break;
    }
    
	//m_eBabyType = _iType;
    m_eBabyPos = _eBabyPos;
    setBabyState(Baby_Entering);
    
    m_bBabySpawned = false;
    
    setFlipHorizontal(_eBabyPos == BabyLeft);
    
	playAction("idle");
    
    if (_sName.compare("chameleon") == 0)
    {
        setColor(Vector4(0,1,0,1));
        int iRand = hRandom::getRandomInt(0, 3);
        switch(iRand)
        {
            case 0:
                m_vChameleonColor = Vector4(1,0,0,1);
                break;
            case 1:
                m_vChameleonColor = Vector4(1,0,1,1);
                break;
            case 2:
                m_vChameleonColor = Vector4(1,1,0,1);
                break;
            case 3:
                m_vChameleonColor = Vector4(0,0,1,1);
                break;
        }
        setColor(Vector4(0,1,0,1));
    }
}

void Baby::setBabyState(eBabyState _iState)
{
    m_eBabyState = _iState;
    m_fStateTimer = 0.0f;
    m_fTimeEnterState = SB::gameTime;

    switch(m_eBabyState)
    {
        case Baby_EatSuccess:
            LevelManager::instance().fedCorrectBaby(this);
            m_bSoundPlayed = false;
            AudioUtils::playSfx("FX_Tragar.mp3");
            playAction("eat_success", true, LevelManager::instance().getGameSpeed());
            if (m_oTongueEyes != NULL)
            {
                m_oTongueEyes->playAction("eat_success", true, LevelManager::instance().getGameSpeed());
            }
            break;
        case Baby_EatFail:
            LevelManager::instance().fedWrongBaby(this);
            m_bSoundPlayed = false;
            AudioUtils::playSfx("FX_Tragar.mp3");
            playAction("eat_fail", true, LevelManager::instance().getGameSpeed());
            if (m_oTongueEyes != NULL)
            {
                m_oTongueEyes->playAction("eat_fail", true, LevelManager::instance().getGameSpeed());
            }
            break;
        case Baby_Exiting:
            switch(m_eBabyPos)
            {
                case BabyLeft:
                    m_vPosOut = Vector2(SB::SCREEN_WIDTH * -0.2, SB::SCREEN_HEIGHT * (LATERAL_CLOUD_HEIGHT + BABY_HEIGHT_OFFSET));
                    m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * -0.2, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
                    break;
                case BabyCenter:
                    m_vPosOut = Vector2(SB::SCREEN_WIDTH * 1.2, SB::SCREEN_HEIGHT * 0.88);
                    m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * 1.2, SB::SCREEN_HEIGHT * 0.75);
                    break;
                case BabyRight:
                    m_vPosOut = Vector2(SB::SCREEN_WIDTH * 1.2, SB::SCREEN_HEIGHT * (LATERAL_CLOUD_HEIGHT + BABY_HEIGHT_OFFSET));
                    m_vCloudPosOut = Vector2(SB::SCREEN_WIDTH * 1.2, SB::SCREEN_HEIGHT * LATERAL_CLOUD_HEIGHT);
                    break;
                default:
                    break;
        }

            break;
        case Baby_Waiting:
            playAction("idle", true, 1.0f);
            if (m_oTongueEyes != NULL)
            {
                m_oTongueEyes->playAction("idle", true, 1.0f);
            }
            m_vPosOut = m_vPosIn;
            break;
        default:
            playAction("idle", true, 1.0f);
            if (m_oTongueEyes != NULL)
            {
                m_oTongueEyes->playAction("idle", true, 1.0f);
            }
            break;
    }
}

void Baby::updateChameleonColor()
{
    if (m_fStateTimer > 1.5f)
    {
        setColor( hMath::blend( getColor(), m_vChameleonColor, 0.5f) );
    }
}

void Baby::tryDisappear()
{
    if (m_eBabyState == Baby_Waiting)
    {
        setBabyState(Baby_Exiting);
    }
}

void Baby::disappear()
{
    if (m_eBabyState != Baby_Exiting && m_eBabyState != Baby_End)
    {
        setBabyState(Baby_Exiting);
    }
}

void Baby::update()
{
    AnimatedEntity::update();
    
    float fGameSpeed = LevelManager::instance().getGameSpeed();
    float fPerc;
    
    m_fStateTimer += SB::dt * fGameSpeed;
    
    if (getEntityName().compare("chameleon") == 0)
    {
        updateChameleonColor();
    }
    
    switch (m_eBabyState) 
    {
        case Baby_Entering:
        {  
            fPerc = fmin(m_fStateTimer / BABY_ENTER_TIME, 1);
            setPosition(m_vPosOut + (m_vPosIn - m_vPosOut) * (pow(fPerc, 2)));
            
            LevelManager::instance().getBabyCloud(m_iCloud)->setPosition(m_vCloudPosOut + (m_vCloudPosIn - m_vCloudPosOut) * fPerc);
            RenderableEntity* oCloud = LevelManager::instance().getBabyShadow(m_iCloud);
            oCloud->setPosition(m_vCloudPosIn);
            oCloud->setScale(Vector2(fPerc * 0.7f, fPerc));
            oCloud->setAlpha(0.2f + fPerc * 0.8f);
            
            
            if(fPerc >= 1)
            {
                setBabyState(Baby_Waiting);
            }
            
            break;
        }   
        case Baby_Waiting:
        {
            float fMove = 20.0f;
            if (m_fStateTimer < 0.1f)
            {
                fPerc = m_fStateTimer / 0.1f;
                setPosition(m_vPosOut - Vector2(0.0f, fMove * fPerc));
            }
            else if (m_fStateTimer < 0.2f)
            {
                fPerc = 1 - ((m_fStateTimer - 0.1f) / 0.1f);
                setPosition(m_vPosOut - Vector2(0.0f, fMove * fPerc));
            }
            break;
        }
        case Baby_EatSuccess:
        case Baby_EatFail:
        {
            float fUpInit = 0.15;
            float fDownInit = 0.25;
            float fDownEnd = 0.35;
            
            if(fPerc >= fUpInit && fPerc < fDownInit)
            {
                fPerc = (fPerc - fUpInit) / (fDownInit - fUpInit);
            }
            else if(fPerc >= fDownInit && fPerc < fDownEnd)
            {
                fPerc = 1 - ((fPerc - fDownInit) / (fDownEnd - fDownInit));
            }
            else
            {
                fPerc = 0;
            }
            
            setPosition(m_vPosIn + Vector2(fPerc * m_vHitDirection.x, fPerc * m_vHitDirection.y));

            if(!m_bSoundPlayed && actionState == "success")
            {
                m_bSoundPlayed = true;
                AudioUtils::playSfx("FX_Success.mp3");
            }
            
            if(!m_bSoundPlayed && actionState == "fail")
            {
                m_bSoundPlayed = true;
                AudioUtils::playSfx("FX_Fail.mp3");
            }
            
            if(actionState == "success_end")
            {
                setBabyState(Baby_Exiting);
            }

            if(actionState == "fail_end")
            {
                setBabyState(Baby_Exiting);
            }
            break;
        }
        case Baby_Exiting:
        {
            fPerc =  fmin(m_fStateTimer / BABY_EXIT_TIME, 1);
            setPosition(m_vPosIn + (m_vPosOut - m_vPosIn) * fPerc);
            LevelManager::instance().getBabyCloud(m_iCloud)->setPosition(m_vCloudPosIn + (m_vCloudPosOut - m_vCloudPosIn) * fPerc);
            LevelManager::instance().getBabyShadow(m_iCloud)->setPosition(m_vCloudPosIn + (m_vCloudPosOut - m_vCloudPosIn) * fPerc);

            if(fPerc >= 1)
            {
                setBabyState(Baby_End);
            }
            break;
        }
        case Baby_End:
            break;
    }
    
    //If it is an animated entity someday...
    LevelManager::instance().getBabyCloud(m_iCloud)->update();
}

void Baby::render()
{
    LevelManager::instance().getBabyCloud(m_iCloud)->render();
    LevelManager::instance().getBabyShadow(m_iCloud)->render(Vector2(0.0f, -10.0f));
    AnimatedEntity::render();
    
    if (m_oTongueEyes != NULL)
    {
        m_oTongueEyes->setPosition(getPosition());
        m_oTongueEyes->setScale(getScale() + Vector2(2.0f, 2.0f));        
        m_oTongueEyes->render();        
    }
}
